package com.nf.mvc.adapter;

import com.nf.mvc.HandlerAdapter;
import com.nf.mvc.MethodArgumentResolver;
import com.nf.mvc.ViewResult;
import com.nf.mvc.argument.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.List;

import static com.nf.mvc.ViewResult.adaptHandlerResult;

public class RequestMappingHandlerAdapter implements HandlerAdapter {

    private List<MethodArgumentResolver> resolvers = new ArrayList<>();

    public RequestMappingHandlerAdapter() {
        //要注意解析器的顺序
        resolvers.add(new ServletApiMethodArgumentResolver());
        resolvers.add(new PartMethodArgumentResolver());
        resolvers.add(new MultipartFileMethodArgumentResolver());
        resolvers.add(new SimpleTypeMethodArgumentResolver());
        resolvers.add(new RequestBodyMethodArgumentResolver());
        //一定要在RequestBodyMethodArgumentResolver这个解析器只有，建议放在最后
        resolvers.add(new PojoMethodArgumentResolver());
    }

    @Override
    public boolean supports(Object handler) {
        return handler instanceof Method ? true : false;
    }

    @Override
    public ViewResult handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        Method m = (Method) handler;
        Object o = m.getDeclaringClass().newInstance();

        Parameter[] parameters = m.getParameters();
        int count = m.getParameterCount();
        Object[] values = new Object[count];

        for (int i = 0; i < parameters.length; i++) {
            Parameter parameter = parameters[i];

            for (MethodArgumentResolver resolver : resolvers) {
                if (resolver.supports(parameter)) {
                    values[i] = resolver.resolveArgument(parameter, request);
                    break;
                }
            }
        }

        Object result = m.invoke(o, values);
        return adaptHandlerResult(result);
    }
}
